package ro.peoplecentric.ctc.faces.util.ui;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.ConverterException;
import javax.faces.convert.FacesConverter;

import ro.peoplecentric.ctc.common.util.ui.SelectItemConvertible;
import ro.peoplecentric.ctc.faces.SelectItemsUtils;

/**
 * Base class for a converter that automatically converts a string
 * representation of an Object back to its original object based on the
 * associated select items for the component for which conversion is taking
 * place.
 * <p>
 * This class can be used as-is provided the Object has a <code>toString</code>
 * method that uniquely identifies it and which makes sense as an identifier.
 * Since this is not the typical case for <code>toString</code>, users are
 * assumed to override the <code>getAsString</code> method and provide an
 * implementation that converts an object to its string representation. This
 * <code>getAsObject</code> method will then be used to automatically do the
 * reverse mapping.
 * <p>
 * This converter is available by converter ID <code>selectItemsConverter</code>
 * . Basic usage example:
 * 
 * <pre>
 * &lt;h:selectOneMenu value="#{bean.selectedEntity}" converter="selectItemsConverter"&gt;
 *   &lt;f:selectItems value="#{bean.availableEntities}" var="entity"
 *     itemValue="#{entity}" itemLabel="#{entity.someProperty}" /&gt;
 * &lt;/h:selectOneMenu&gt;
 * </pre>
 * <p>
 * 
 * @author pguzun
 */
@FacesConverter("selectItemsConverter")
public class SelectItemsConverter implements Converter {

	@Override
	public Object getAsObject(FacesContext context, UIComponent component, String value) {
		return SelectItemsUtils.findValueByStringConversion(context, component, value, this);
	}

	@Override
	public String getAsString(FacesContext context, UIComponent component, Object value) {
		if (value == null) {
			return "";
		}

		if (value instanceof SelectItemConvertible) {
			return String.valueOf(((SelectItemConvertible) value).getId());
		} else {
			throw new ConverterException("Exception occured when converting object '" + value.toString()
					+ "'. The given object is not instance of " + SelectItemConvertible.class.getName());
		}
	}

}
